#!/bin/bash
###############################################################################
#       脚本名称: test_logger_console.sh
#       功能描述: 控制台日志输出器单元测试
#       作者: 林再来
#       日期: 2025-10-28
#       版本: 1.0
#       功能:
#           1、测试控制台彩色输出功能
#           2、测试stdout和stderr输出切换
#           3、测试不同日志级别的颜色显示
#           4、测试终端颜色检测功能
#           5、测试配置项设置和获取
#       依赖(插件/命令):
#           无
###############################################################################

# 获取脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"

# 加载测试框架
source "$SCRIPT_DIR/../test_framework.sh"

# 加载被测模块
source "$PROJECT_ROOT/scripts/logger/appender/appender_console.sh"
source "$PROJECT_ROOT/scripts/logger/formatter/formatter_plain.sh"
source "$PROJECT_ROOT/scripts/logger/formatter/formatter_json.sh"

###############################################################################
# 测试用例
###############################################################################

#-----------------------------------------------------------------------------
# 测试: 控制台输出器初始化
#-----------------------------------------------------------------------------
function test_console_init() {
    # 初始化控制台输出器
    _appender_console_init "test_console"
    
    # 验证配置已设置
    local color="${_CONSOLE_APPENDER_CONFIGS[test_console_color]}"
    local target="${_CONSOLE_APPENDER_CONFIGS[test_console_target]}"
    
    assert_not_empty "$color" "颜色配置不应为空"
    assert_not_empty "$target" "目标配置不应为空"
    
    # 清理
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 控制台输出器配置设置
#-----------------------------------------------------------------------------
function test_console_set_config() {
    _appender_console_init "test_console"
    
    # 测试设置颜色配置
    _appender_console_set_config "test_console" "color" "true"
    assert_equals "true" "${_CONSOLE_APPENDER_CONFIGS[test_console_color]}" \
        "颜色配置应为true"
    
    # 测试设置目标配置
    _appender_console_set_config "test_console" "target" "stderr"
    assert_equals "stderr" "${_CONSOLE_APPENDER_CONFIGS[test_console_target]}" \
        "目标配置应为stderr"
    
    # 测试设置无效配置项（应失败）
    if _appender_console_set_config "test_console" "invalid_key" "value" 2>/dev/null; then
        echo "设置无效配置项应该失败" >&2
        return 1
    fi
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 基本日志输出到stdout
#-----------------------------------------------------------------------------
function test_console_write_stdout() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "false"
    _appender_console_set_config "test_console" "target" "stdout"
    
    # 构造测试事件
    local event='{"timestamp":"2025-10-28 10:00:00","level":"INFO","message":"测试消息"}'
    local formatted="[INFO] 2025-10-28 10:00:00 - 测试消息"
    
    # 捕获输出
    local output
    output=$(_appender_console_write "test_console" "$formatted" "$event" 2>&1)
    
    # 验证输出包含消息
    assert_contains "$output" "测试消息" "输出应包含测试消息"
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 日志输出到stderr
#-----------------------------------------------------------------------------
function test_console_write_stderr() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "false"
    _appender_console_set_config "test_console" "target" "stderr"
    
    local event='{"timestamp":"2025-10-28 10:00:00","level":"ERROR","message":"错误消息"}'
    local formatted="[ERROR] 2025-10-28 10:00:00 - 错误消息"
    
    # stderr输出应该能被2>&1捕获
    local output
    output=$(_appender_console_write "test_console" "$formatted" "$event" 2>&1)
    
    assert_contains "$output" "错误消息" "stderr输出应包含错误消息"
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 彩色输出（启用颜色）
#-----------------------------------------------------------------------------
function test_console_color_enabled() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "true"
    _appender_console_set_config "test_console" "target" "stdout"
    
    # 测试不同级别的彩色输出
    local levels=("TRACE" "DEBUG" "INFO" "WARN" "ERROR" "FATAL")
    
    for level in "${levels[@]}"; do
        local event="{\"timestamp\":\"2025-10-28 10:00:00\",\"level\":\"$level\",\"message\":\"${level}消息\"}"
        local formatted="[$level] 2025-10-28 10:00:00 - ${level}消息"
        
        local output
        output=$(_appender_console_write "test_console" "$formatted" "$event" 2>&1)
        
        # 验证输出包含消息内容
        assert_contains "$output" "${level}消息" "${level}级别输出应包含消息"
    done
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 彩色输出（禁用颜色）
#-----------------------------------------------------------------------------
function test_console_color_disabled() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "false"
    _appender_console_set_config "test_console" "target" "stdout"
    
    local event='{"timestamp":"2025-10-28 10:00:00","level":"INFO","message":"测试消息"}'
    local formatted="[INFO] 2025-10-28 10:00:00 - 测试消息"
    
    local output
    output=$(_appender_console_write "test_console" "$formatted" "$event" 2>&1)
    
    # 验证输出包含消息（不应包含ANSI颜色码）
    assert_contains "$output" "测试消息" "输出应包含测试消息"
    # 不应包含颜色码（如\033[）
    if echo "$output" | grep -q $'\033\['; then
        echo "禁用颜色时不应包含ANSI颜色码" >&2
        return 1
    fi
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 自动颜色检测
#-----------------------------------------------------------------------------
function test_console_color_auto() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "auto"
    _appender_console_set_config "test_console" "target" "stdout"
    
    local event='{"timestamp":"2025-10-28 10:00:00","level":"WARN","message":"警告消息"}'
    local formatted="[WARN] 2025-10-28 10:00:00 - 警告消息"
    
    # auto模式会根据终端环境自动判断
    local output
    output=$(_appender_console_write "test_console" "$formatted" "$event" 2>&1)
    
    assert_contains "$output" "警告消息" "输出应包含警告消息"
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 终端颜色支持检测
#-----------------------------------------------------------------------------
function test_console_supports_color() {
    # 测试颜色支持检测功能
    # 这个测试结果依赖于运行环境
    
    # 保存原始环境
    local old_term="${TERM:-}"
    local old_no_color="${NO_COLOR:-}"
    
    # 测试1: 设置TERM为dumb（不支持颜色）
    export TERM="dumb"
    if _console_supports_color; then
        echo "TERM=dumb时应该返回不支持颜色" >&2
        return 1
    fi
    
    # 测试2: 设置NO_COLOR=1（禁用颜色）
    export TERM="xterm-256color"
    export NO_COLOR="1"
    if _console_supports_color; then
        echo "NO_COLOR=1时应该返回不支持颜色" >&2
        return 1
    fi
    
    # 恢复环境
    if [[ -n "$old_term" ]]; then
        export TERM="$old_term"
    else
        unset TERM
    fi
    
    if [[ -n "$old_no_color" ]]; then
        export NO_COLOR="$old_no_color"
    else
        unset NO_COLOR
    fi
}

#-----------------------------------------------------------------------------
# 测试: 刷新和关闭操作
#-----------------------------------------------------------------------------
function test_console_flush_and_close() {
    _appender_console_init "test_console"
    
    # 刷新操作（控制台无缓冲，应该成功返回）
    _appender_console_flush "test_console"
    local flush_result=$?
    assert_equals "0" "$flush_result" "刷新操作应成功"
    
    # 关闭操作
    _appender_console_close "test_console"
    
    # 验证配置已清理
    local color="${_CONSOLE_APPENDER_CONFIGS[test_console_color]:-}"
    assert_empty "$color" "关闭后配置应被清理"
}

#-----------------------------------------------------------------------------
# 测试: 无事件JSON的输出
#-----------------------------------------------------------------------------
function test_console_write_without_event() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "false"
    _appender_console_set_config "test_console" "target" "stdout"
    
    # 不提供事件JSON，只提供格式化文本
    local formatted="[INFO] 简单日志消息"
    
    local output
    output=$(_appender_console_write "test_console" "$formatted" "" 2>&1)
    
    assert_contains "$output" "简单日志消息" "输出应包含消息"
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 多行消息输出
#-----------------------------------------------------------------------------
function test_console_multiline_message() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "false"
    _appender_console_set_config "test_console" "target" "stdout"
    
    local multiline_msg="第一行\\n第二行\\n第三行"
    local event="{\"timestamp\":\"2025-10-28 10:00:00\",\"level\":\"INFO\",\"message\":\"多行消息\"}"
    local formatted="[INFO] 2025-10-28 10:00:00 - ${multiline_msg}"
    
    local output
    output=$(_appender_console_write "test_console" "$formatted" "$event" 2>&1)
    
    assert_not_empty "$output" "多行消息输出不应为空"
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 特殊字符处理
#-----------------------------------------------------------------------------
function test_console_special_characters() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "false"
    _appender_console_set_config "test_console" "target" "stdout"
    
    # 包含特殊字符的消息
    local special_msg="包含特殊字符: @#\$%^&*()[]{}|\\;:'\",<>?"
    local event="{\"timestamp\":\"2025-10-28 10:00:00\",\"level\":\"INFO\",\"message\":\"特殊字符\"}"
    local formatted="[INFO] 2025-10-28 10:00:00 - ${special_msg}"
    
    local output
    output=$(_appender_console_write "test_console" "$formatted" "$event" 2>&1)
    
    assert_not_empty "$output" "包含特殊字符的输出不应为空"
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 连续多次写入
#-----------------------------------------------------------------------------
function test_console_multiple_writes() {
    _appender_console_init "test_console"
    _appender_console_set_config "test_console" "color" "false"
    _appender_console_set_config "test_console" "target" "stdout"
    
    local count=10
    local i
    
    for ((i=1; i<=count; i++)); do
        local event="{\"timestamp\":\"2025-10-28 10:00:00\",\"level\":\"INFO\",\"message\":\"消息${i}\"}"
        local formatted="[INFO] 2025-10-28 10:00:00 - 消息${i}"
        
        _appender_console_write "test_console" "$formatted" "$event" >/dev/null 2>&1
    done
    
    # 所有写入都应成功（通过没有抛出异常来验证）
    
    _appender_console_close "test_console"
}

#-----------------------------------------------------------------------------
# 测试: 配置项验证
#-----------------------------------------------------------------------------
function test_console_config_validation() {
    _appender_console_init "test_console"
    
    # 测试有效的颜色配置值
    _appender_console_set_config "test_console" "color" "true"
    assert_equals "true" "${_CONSOLE_APPENDER_CONFIGS[test_console_color]}"
    
    _appender_console_set_config "test_console" "color" "false"
    assert_equals "false" "${_CONSOLE_APPENDER_CONFIGS[test_console_color]}"
    
    _appender_console_set_config "test_console" "color" "auto"
    assert_equals "auto" "${_CONSOLE_APPENDER_CONFIGS[test_console_color]}"
    
    # 测试无效的颜色配置值（应该失败）
    if _appender_console_set_config "test_console" "color" "invalid" 2>/dev/null; then
        echo "设置无效的颜色值应该失败" >&2
        return 1
    fi
    
    # 测试有效的目标配置值
    _appender_console_set_config "test_console" "target" "stdout"
    assert_equals "stdout" "${_CONSOLE_APPENDER_CONFIGS[test_console_target]}"
    
    _appender_console_set_config "test_console" "target" "stderr"
    assert_equals "stderr" "${_CONSOLE_APPENDER_CONFIGS[test_console_target]}"
    
    # 测试无效的目标配置值（应该失败）
    if _appender_console_set_config "test_console" "target" "invalid" 2>/dev/null; then
        echo "设置无效的目标值应该失败" >&2
        return 1
    fi
    
    _appender_console_close "test_console"
}

###############################################################################
# 运行所有测试
###############################################################################

function run_all_tests() {
    test_suite_start "控制台输出器单元测试"
    
    run_test "控制台输出器初始化" test_console_init
    run_test "控制台输出器配置设置" test_console_set_config
    run_test "基本日志输出到stdout" test_console_write_stdout
    run_test "日志输出到stderr" test_console_write_stderr
    run_test "彩色输出（启用）" test_console_color_enabled
    run_test "彩色输出（禁用）" test_console_color_disabled
    run_test "自动颜色检测" test_console_color_auto
    run_test "终端颜色支持检测" test_console_supports_color
    run_test "刷新和关闭操作" test_console_flush_and_close
    run_test "无事件JSON的输出" test_console_write_without_event
    run_test "多行消息输出" test_console_multiline_message
    run_test "特殊字符处理" test_console_special_characters
    run_test "连续多次写入" test_console_multiple_writes
    run_test "配置项验证" test_console_config_validation
    
    test_suite_end
}

# 主函数
function main() {
    run_all_tests
    test_report
    exit_with_test_result
}

# 如果直接执行此脚本，运行所有测试
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main
fi

